package com.tbit.uqbike.client.pojo.vo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: chen
 * @Description: 计算点到多边形距离
 * @Date: 创建于 17:34 2020/12/3
 */
public class PointVo {

    private BigDecimal x;

    private BigDecimal y;

    public PointVo(double x, double y) {
        this.x = new BigDecimal(x);
        this.y = new BigDecimal(y);
    }

    public PointVo(BigDecimal x, BigDecimal y) {
        this.x = x;
        this.y = y;
    }

    public static void main(String[] args) {

        // 地图上画一个多边形 113.887058,22.733709;113.887061,22.7336;113.888854,22.733566;113.888847,22.733664
    /*Point[] points = {
        new Point(22.733709, 113.887058),
        new Point(22.7336, 113.887061),
        new Point(22.733566, 113.888854),
        new Point(22.733664, 113.888847)
    };
    // 地图多边形内随机某一点
    Point p = new Point(22.73353, 113.88852);
116.271452,32.355436;116.271419,32.355445;116.271324,32.355124;116.270847,32.353977;116.270889,32.353968;116.271363,32.355112
    // 当前点到多边形各边的距离 lo :116.27162,la :32.35505
    for (int i = 0; i < points.length; i++) {
      System.out.println("distance=" + p.distance(points[i], points[i == points.length - 1 ? 0 : i+1]) + "米");
    }*/
        //113.887096,22.733788;113.887061,22.7336;113.888854,22.733566;113.888847,22.733753
        //p1.setX(113.888255);
        //    p1.setY(22.733507777777778);
        List<PointVo> list = new ArrayList<>();
        list.add(new PointVo(22.733788, 113.887096));
        list.add(new PointVo(22.7336, 113.887061));
        list.add(new PointVo(22.733753, 113.888854));
        PointVo p = new PointVo(22.733507777777778, 113.888255);
        System.out.println(p.getDistance(list));
    }

    /**
     * 当前点和顶点之间构成的余弦值平方
     *
     * @param p
     * @return
     */
    private BigDecimal cos2(PointVo p) {
        BigDecimal vector2 = (p.x.subtract(x).pow(2)).add(p.y.subtract(y).pow(2));
        return (p.x.subtract(x).pow(2)).divide(vector2, 11, BigDecimal.ROUND_HALF_DOWN);
    }

    /**
     * 当前点到顶点之间的Y向量差
     *
     * @param p
     * @return
     */
    private BigDecimal toY(PointVo p) {
        return p.y.subtract(y);
    }

    /**
     * 当前点到顶点之间的x向量差
     *
     * @param p
     * @return
     */
    private BigDecimal toX(PointVo p) {
        return p.x.subtract(x);
    }

    /**
     * 1度多少米
     *
     * @return
     */
    private BigDecimal itude1() {
        return new BigDecimal(Math.cos(y.doubleValue())).multiply(new BigDecimal(111194.92474777778)).abs();
    }

    /**
     * 当前顶点到两点之间的距离
     *
     * @param pb 起始点
     * @param pe 结束点
     * @return
     */
    public double distance(PointVo pb, PointVo pe) {
        if (pe.toX(pb).doubleValue() == 0) {
            BigDecimal dist2 = pe.toY(this).pow(2);
            return itude1().multiply(new BigDecimal(Math.sqrt(dist2.doubleValue()))).doubleValue();
        } else {
            BigDecimal vector = pe.toY(pb).multiply(toX(pb)).divide(pe.toX(pb), 11, BigDecimal.ROUND_HALF_DOWN).subtract(toY(pb));
            BigDecimal dist2 = pb.cos2(pe).multiply(vector.pow(2));
            return itude1().multiply(new BigDecimal(Math.sqrt(dist2.doubleValue()))).doubleValue();
        }
    }

    /**
     * 获取最近距离
     *
     * @param list
     * @return
     */
    public double getDistance(List<PointVo> list) {
        Double min = null;
        for (int i = 0; i < list.size(); i++) {
            double distance = distance(list.get(i), list.get(i == list.size() - 1 ? 0 : i + 1));
            if (min == null) {
                min = distance;
            }
            if (min != null && min > distance) {
                min = distance;
            }
        }
        return min;
    }


}
